home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / gs261sr1.zip / GDEVPCFB.C < prev    next >
C/C++ Source or Header  |  1993-05-12  |  23KB  |  858 lines

  1. /* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* gdevpcfb.c */
  20. /* IBM PC EGA and VGA display drivers for Ghostscript */
  21. /* This is fundamentally an EGA driver with some parameters */
  22. /* that allow it to drive larger displays. */
  23. #include "memory_.h"
  24. #include "gx.h"
  25. #include "gserrors.h"
  26. #include "gxdevice.h"
  27. #include "gdevpcfb.h"
  28.  
  29. /* Macro for casting gx_device argument */
  30. #define fb_dev ((gx_device_ega *)dev)
  31.  
  32. /* Define the color spectrum */
  33. #define black 0
  34. #define blue 1
  35. #define green 2
  36. #define cyan 3
  37. #define red 4
  38. #define magenta 5
  39. #define brown 6
  40. #define white 7
  41. #define dgray 8                /* dark gray is not very usable */
  42. #define lblue 9
  43. #define lgreen 10
  44. #define lcyan 11
  45. #define lred 12
  46. #define lmagenta 13
  47. #define yellow 14
  48. #define bwhite 15
  49.  
  50. /* Procedure record */
  51. private gx_device_procs ega_procs = {
  52.     ega_open,
  53.     gx_default_get_initial_matrix,
  54.     gx_default_sync_output,
  55.     gx_default_output_page,
  56.     ega_close,
  57.     ega_map_rgb_color,
  58.     ega_map_color_rgb,
  59.     ega_fill_rectangle,
  60.     ega_tile_rectangle,
  61.     ega_copy_mono,
  62.     ega_copy_color,
  63.     gx_default_draw_line,
  64.     ega_get_bits,
  65.     gx_default_get_props,
  66.     gx_default_put_props
  67. };
  68.  
  69. /* All the known instances */
  70.         /* EGA */
  71. gx_device_ega gs_ega_device =
  72.     ega_device("ega", ega_procs, 80, 350, 48.0/35.0, 0x10);
  73.         /* VGA */
  74. gx_device_ega gs_vga_device =
  75.     ega_device("vga", ega_procs, 80, 480, 1.0, 0x12);
  76.         /* ATI Wonder SuperVGA, 800x600, 16-color mode */
  77. gx_device_ega gs_atiw16_device =
  78.     ega_device("atiw16", ega_procs, 100, 600, 1.0, 0x54);
  79.         /* Trident SuperVGA, 800x600, 16-color mode */
  80. gx_device_ega gs_tvga16_device =
  81.     ega_device("tvga16", ega_procs, 100, 600, 1.0, 0x5b);
  82.         /* Tseng Labs SuperVGA, 800x600, 16-color mode */
  83. gx_device_ega gs_tseng16_device =
  84.     ega_device("tseng16", ega_procs, 100, 600, 1.0, 0x29);
  85.  
  86. /* Save the EGA mode */
  87. private int ega_save_mode = -1;
  88.  
  89. /* Initialize the EGA for graphics mode */
  90. int
  91. ega_open(gx_device *dev)
  92. {    /* Adjust the device resolution. */
  93.     /* This is a hack, pending refactoring of the put_props machinery. */
  94.     switch ( fb_dev->video_mode )
  95.     {
  96.     case 0x10:    /* EGA */
  97.         gx_device_adjust_resolution(dev, 640, 350, 1); break;
  98.     case 0x12:    /* VGA */
  99.         gx_device_adjust_resolution(dev, 640, 480, 1); break;
  100.     case 0x54:      /* ATI Wonder */
  101.     case 0x5b:    /* Trident */
  102.     case 0x29:    /* Tseng */
  103.         gx_device_adjust_resolution(dev, 800, 600, 1); break;
  104.     }
  105.     if ( ega_save_mode < 0 )
  106.         ega_save_mode = ega_get_mode();
  107.     /* Do implementation-specific initialization */
  108.     ega_set_signals(dev);
  109.     ega_set_mode(fb_dev->video_mode);
  110.     set_s_map(-1);            /* enable all maps */
  111.     return 0;
  112. }
  113.  
  114. /* Reinitialize the EGA for text mode */
  115. int
  116. ega_close(gx_device *dev)
  117. {    if ( ega_save_mode >= 0 )
  118.         ega_set_mode(ega_save_mode);
  119.     return 0;
  120. }
  121.  
  122. /* Map a r-g-b color to an EGA color code. */
  123. gx_color_index
  124. ega_map_rgb_color(gx_device *dev, gx_color_value r, gx_color_value g,
  125.   gx_color_value b)
  126. {
  127. #define c12 (gx_max_color_value / 2)
  128. #define c13 (gx_max_color_value / 3)
  129. #define c23 (gx_max_color_value - c13)
  130. #define cmono() ((gx_color_index)mono_color[r >> (gx_color_value_bits - 2)])
  131. #if ega_bits_of_color == 0        /* monochrome */
  132.     static const byte mono_color[4] = { black, white, white, bwhite };
  133.     return cmono();
  134. #else
  135. # if ega_bits_of_color == 1
  136.     static const byte mono_color[4] = { black, white, white, bwhite };
  137.     if ( r == g && g == b )
  138.         return cmono();
  139.     return (gx_color_index)
  140.         ((r > c12 ? 4 : 0) |
  141.          (g > c12 ? 10 : 0) |
  142.          (b > c12 ? 1 : 0));
  143. # else
  144.     static const byte g0[3][3] =
  145.      {{black,blue,lblue},{red,magenta,lmagenta},{lred,lmagenta,lmagenta}};
  146.     static const byte g1[3][3] =
  147.      {{green,cyan,lcyan},{brown,white,lcyan},{yellow,yellow,lmagenta}};
  148.     static const byte g2[3][3] =
  149.      {{lgreen,lgreen,lcyan},{lgreen,lgreen,lcyan},{yellow,yellow,bwhite}};
  150.     return (gx_color_index)
  151.         ((g >= c23 ? g2 : g >= c13 ? g1 : g0)
  152.          [r >= c23 ? 2 : r >= c13 ? 1 : 0]
  153.          [b >= c23 ? 2 : b >= c13 ? 1 : 0]);
  154. # endif
  155. #endif
  156. #undef c12
  157. #undef c13
  158. #undef c23
  159. }
  160.  
  161. /* Map a color code to r-g-b. */
  162. int
  163. ega_map_color_rgb(gx_device *dev, gx_color_index color,
  164.   gx_color_value prgb[3])
  165. {
  166. #define icolor (int)color
  167. #if rgb_max > 1
  168.     gx_color_value one =
  169.         (icolor & 8 ? gx_max_color_value : gx_max_color_value / 3);
  170. #else
  171. #  define one (gx_max_color_value / 2 + 1)
  172. #endif
  173.     prgb[0] = (icolor & 4 ? one : 0);
  174.     prgb[1] = (icolor & 2 ? one : 0);
  175.     prgb[2] = (icolor & 1 ? one : 0);
  176.     return 0;
  177. #undef one
  178. #undef icolor
  179. }
  180.  
  181. /* ------ Internal routines ------ */
  182.  
  183. /* Structure for operation parameters. */
  184. /* Note that this structure is known to assembly code. */
  185. /* Not all parameters are used for every operation. */
  186. typedef struct rop_params_s {
  187.     fb_ptr dest;            /* pointer to frame buffer */
  188.     int draster;            /* raster of frame buffer */
  189.     const byte *src;        /* pointer to source data */
  190.     int sraster;            /* source raster */
  191.     int width;            /* width in bytes */
  192.     int height;            /* height in scan lines */
  193.     int shift;            /* amount to right shift source */
  194.     int invert;            /* 0 or -1 to invert source */
  195.     int data;            /* data for fill */
  196. } rop_params;
  197. typedef rop_params _ss *rop_ptr;
  198.  
  199. /* Assembly language routines */
  200.  
  201. #if USE_ASM
  202. void memsetcol(P1(rop_ptr)); /* dest, draster, height, data */
  203. #else
  204. #define memsetcol cmemsetcol
  205. private void
  206. cmemsetcol(rop_ptr rop)
  207. {    byte *addr = rop->dest;
  208.     int yc = rop->height;
  209.     byte data = rop->data;
  210.     int draster = rop->draster;
  211.     while ( yc-- )
  212.      { byte_discard(*addr);
  213.        *addr = data;
  214.        addr += draster;
  215.      }
  216. }
  217. #endif
  218.  
  219. #if USE_ASM
  220. void memsetrect(P1(rop_ptr)); /* dest, draster, width, height, data */
  221. #else
  222. #define memsetrect cmemsetrect
  223. private void
  224. cmemsetrect(rop_ptr rop)
  225. {    int yc = rop->height;
  226.     int width = rop->width;
  227.     if ( yc <= 0 || width <= 0 ) return;
  228.        {    byte *addr = rop->dest;
  229.         byte data = rop->data;
  230.         if ( width > 5 )    /* use memset */
  231.            {    int skip = rop->draster;
  232.             do
  233.                {    memset(addr, data, width);
  234.                 addr += skip;
  235.                }
  236.             while ( --yc );
  237.            }
  238.         else            /* avoid the fixed overhead */
  239.            {    int skip = rop->draster - width;
  240.             do
  241.                {    int cnt = width;
  242.                 do { *addr++ = data; } while ( --cnt );
  243.                 addr += skip;
  244.                }
  245.             while ( --yc );
  246.            }
  247.        }
  248. }
  249. #endif
  250.  
  251. #if USE_ASM
  252. void memrwcol(P1(rop_ptr)); /* dest, draster, src, sraster, height, shift, invert */
  253. #  define memrwcol0(rop) memrwcol(rop)    /* same except shift = 0 */
  254. #else
  255. #  define memrwcol cmemrwcol
  256. #  define memrwcol0 cmemrwcol0
  257. private void
  258. cmemrwcol(rop_ptr rop)
  259. {    byte *dp = rop->dest;
  260.     const byte *sp = rop->src;
  261.     int yc = rop->height;
  262.     int shift = rop->shift;
  263.     byte invert = rop->invert;
  264.     int sraster = rop->sraster, draster = rop->draster;
  265.     while ( yc-- )
  266.      { byte_discard(*dp);
  267.        *dp = ((*sp >> shift) + (*sp << (8 - shift))) ^ invert;
  268.        dp += draster, sp += sraster;
  269.      }
  270. }
  271. private void
  272. cmemrwcol0(rop_ptr rop)
  273. {    byte *dp = rop->dest;
  274.     const byte *sp = rop->src;
  275.     int yc = rop->height;
  276.     byte invert = rop->invert;
  277.     int sraster = rop->sraster, draster = rop->draster;
  278.     if ( yc > 0 ) do
  279.      { byte_discard(*dp);
  280.        *dp = *sp ^ invert;
  281.        dp += draster, sp += sraster;
  282.      }
  283.     while ( --yc );
  284. }
  285. #endif
  286.  
  287. #if USE_ASM
  288. void memrwcol2(P1(rop_ptr)); /* dest, draster, src, sraster, height, sh